package sql.parser;

import org.apache.commons.lang3.StringUtils;
import sql.lexer.Keywords;
import sql.lexer.SQLLexer;
import sql.lexer.Token;
import sql.lexer.TokenType;

public abstract class SyntaxJudge {
    private final SQLLexer lexer;
    private Token token;

    public SyntaxJudge(SQLLexer lexer) {
        this.lexer = lexer;
    }

    protected String getStrToken() {
        return this.token.value;
    }

    protected void nextToken() {
        token = this.lexer.nextToken();
        if(token.type == TokenType.INVALID) {
            throw new RuntimeException("SQL语法错误");
        }
    }

    protected boolean isEnd() {
        return  token.type == TokenType.EOF;
    }

    protected SyntaxType getSyntaxType() {
        TokenType type = token.type;
        switch (type) {
            case LEFT_PAREN:
                return SyntaxType.BracketStart;
            case RIGHT_PAREN:
                return SyntaxType.BracketEnd;
            case COMMA:
                return SyntaxType.Comma;
            case EQUALS,
                 NOT_EQUALS,
                 LESS_EQUAL,
                 LESS_THAN,
                 GREATER_EQUAL,
                 GREATER_THAN:
                return SyntaxType.Op;
            case NUMBER:
                return SyntaxType.Number;
            case STRING:
                return SyntaxType.String;
            case IDENTIFIER:
                return SyntaxType.Identifier;
            case STAR:
                return SyntaxType.Star;
            case EOF:
                return SyntaxType.EOF;
            case KEYWORD: {
                String strToken = getStrToken();
                switch (strToken) {
                    case Keywords.SELECT:
                        return SyntaxType.Select;
                    case Keywords.FROM:
                        return SyntaxType.From;
                    case Keywords.WHERE:
                        return SyntaxType.Where;
                    case Keywords.IN:
                        return SyntaxType.In;
                    case Keywords.AS:
                        return SyntaxType.As;
                    case Keywords.INSERT:
                        return SyntaxType.Insert;
                    case Keywords.INTO:
                        return SyntaxType.Into;
                    case Keywords.VALUES:
                        return SyntaxType.Values;
                    case Keywords.UPDATE:
                        return SyntaxType.Update;
                    case Keywords.SET:
                        return SyntaxType.Set;
                    case Keywords.ORDER:
                        return SyntaxType.Order;
                    case Keywords.BY:
                        return SyntaxType.By;
                    case Keywords.ASC:
                        return SyntaxType.OrderByAsc;
                    case Keywords.DESC:
                        return SyntaxType.OrderByDesc;
                    case Keywords.LIMIT:
                        return SyntaxType.limit;
                    case Keywords.AND:
                        return SyntaxType.And;
                    case Keywords.OR:
                        return SyntaxType.Or;
                    case Keywords.DELETE:
                        return SyntaxType.Delete;
                }
            }
            default:
                throw new RuntimeException(String.format("不支持该类型token，tokenType:%s, token:%s", token.type, token.value));
        }
    }

    public boolean isElement(SyntaxType type) {
        return type == SyntaxType.Star || type == SyntaxType.Number || type == SyntaxType.String || type == SyntaxType.Identifier;
    }
}
